home *** CD-ROM | disk | FTP | other *** search
-
- PUBLIC DDIIL
-
- ASSUME CS:$DDIIL
-
- INCLUDE DOS.INC
-
- $DDIIL SEGMENT PARA PUBLIC 'CODE'
-
- COMMENT \ Procedure/Function : DDIIL
-
- PROCEDURE DDISB (MX,MY : integer); EXTERNAL;
-
- PROCEDURE DDIIL (IX0,IY0,IX1,IY1 : integer; VISBLE : boolean);
- {
- (Incremental Line)
- Fill in the steps on the plot frame between the point (IX0,IY0) and
- (IX1,IY1), where IX0, IY0, IX1, and IY1 are in actual raster units for
- the device being used. If a vector plot device is to be used, this
- routine might instead simply transmit a single vector to a buffer.
-
- This version uses a symmetric DDA algorithm due to Van Throng (?).
- (25-JAN-84)
- }
- VAR
- AXIS, AXISX, AXISY, BIAS, DELX, DELY, DIAG, DIAGX, DIAGY, I, IX,
- IY, NDIST, NUMPNT, SX, SY : INTEGER;
-
- Here is the Pascal code corresponding to the assembly code below. Line
- number labels are retained, but hand optimization of the .COD file
- produced by the IBM Pascal Version 1.00 compiler for the IBM PC with the
- debug code suppressed has substantially reduced the code size and
- resulted in some minor rearrangements.
-
- L44: IF VISBLE THEN
- L45: BEGIN
- L46: DELX := IX1 - IX0;
- L47: DELY := IY1 - IY0;
- L48: SX := ABS(DELY);
- L49: SY := ABS(DELX);
- L50: IF DELX >= 0
- L51: THEN DIAGX := 1
- L52: ELSE DIAGX := -1;
- L53: IF DELY >= 0
- L54: THEN DIAGY := 1
- L55: ELSE DIAGY := -1;
- L56: IF SY <= SX THEN
- L57: BEGIN
- L58: AXISX := 0;
- L59: AXISY := DIAGY
- L60: END
- L61: ELSE
- L62: BEGIN
- L63: AXISX := DIAGX;
- L64: AXISY := 0
- L65: END;
- L66: AXIS := MIN(SX,SY);
- L67: BIAS := MAX(SX,SY);
- L68: DIAG := AXIS - BIAS;
- L69: IF DIAGX < 0
- L70: THEN NDIST := - BIAS - 2
- L71: ELSE NDIST := - BIAS - 1;
- L72: NDIST := AXIS + NDIST DIV 2;
- L73: NUMPNT := MAX(SX,SY) + 1;
- L74: IX := IX0;
- L75: IY := IY0;
- L76: FOR I := 1 TO NUMPNT-1 DO
- L77: BEGIN
- L78: DDISB (IX,IY);
- L79: IF NDIST < 0 THEN
- L80: BEGIN
- L81: NDIST := NDIST + AXIS;
- L82: IX := IX + AXISX;
- L83: IY := IY + AXISY
- L84: END
- L85: ELSE
- L86: BEGIN
- L87: NDIST := NDIST + DIAG;
- L88: IX := IX + DIAGX;
- L89: IY := IY + DIAGY
- L90: END
- L91: END;
- L92: DDISB(IX,IY)
- L93: END
- L94: END; { DDIIL }
- \
-
- ARGCNT EQU 5 ; Number of arguments
- IX0 EQU [BP] ; Define symbolic argument frame offsets
- IY0 EQU [BP-2]
- IX1 EQU [BP-4]
- IY1 EQU [BP-6]
- VISBLE EQU [BP-8]
- ; return address as CS:offset at [BP-10..13]
- ; old BP at [BP-14..15]
- AXISX EQU [BP-16] ; start of local variables
- AXISY EQU [BP-18]
- BIAS EQU [BP-20]
- DELX EQU [BP-22]
- DELY EQU [BP-24]
- DIAG EQU [BP-26]
- DIAGX EQU [BP-28]
- DIAGY EQU [BP-30]
- I EQU [BP-32]
- IX EQU [BP-34]
- IY EQU [BP-36]
- NDIST EQU [BP-38]
- NUMPNT EQU [BP-40]
- SX EQU [BP-42]
- SY EQU [BP-44]
- AXIS EQU [BP-46]
- SPBIAS EQU 46 ; New SP points at last local stack variable
-
-
- DDIIL PROC FAR
- PUSH BP ; Save caller's frame pointer
- MOV BP,SP ; and set up our own.
- ADD BP,4+2*ARGCNT ; Point to top of arg list on stack
- SUB SP,SPBIAS ; Reserve space for locals on stack
- ; (stack overflow not checked for)
- L44:
- MOV DX,VISBLE
- TEST DL,DL ; VISBLE = false?
- JNZ L46 ; No
- ADD SP,SPBIAS ; Yes, restore original SP at entry
- POP BP ; and caller's frame pointer
- RET 2*ARGCNT ; and return discarding stack arguments
-
- L46:
- MOV DX,IX1
- SUB DX,IX0
- MOV DELX,DX ; DELX := IX1 - IX0
- L47:
- MOV DX,IY1
- SUB DX,IY0
- MOV DELY,DX ; DELY := IY1 - IY0
- L48:
- MOV DX,DELY
- MOV CX,1
- TEST DX,DX ; DELY < 0?
- JNS L48a ; No
- NEG DX ; Yes, make positive
- NEG CX ; -1
- L48a:
- MOV SX,DX ; SX := ABS(DELY)
- MOV DIAGY,CX ; DIAGY := SIGN(1,DELY)
- L49:
- MOV DX,DELX
- MOV CX,1
- TEST DX,DX ; DELX < 0?
- JNS L49a ; No
- NEG DX ; Yes, make positive
- NEG CX ; -1
- L49a:
- MOV SY,DX ; SY := ABS(DELX)
- MOV DIAGX,CX ; DIAGX := SIGN(1,DELX)
- L50:
- L51:
- L52:
- L53:
- L54:
- L55:
- L56:
- MOV DX,SY
- CMP DX,SX ; SY > SX?
- JG I12 ; Yes
- L58: ; No, SY <= SX
- MOV word ptr AXISX,0000H ; AXISX := 0
- L59:
- MOV DX,DIAGY
- MOV AXISY,DX ; AXISY := DIAGY
- JMP short I13
- I12: ; else (SY > SX)
- L63:
- MOV DX,DIAGX
- MOV AXISX,DX ; AXISX := DIAGX
- L64:
- MOV word ptr AXISY,0000H ; AXISY := 0
- L65:
- I13:
- L66:
- MOV DX,SX
- MOV CX,SY
- CMP DX,CX ; SX > SY?
- JG L66a ; Yes
- MOV AXIS,DX ; No, AXIS = min(SX,SY) = SX
- MOV BIAS,CX ; and BIAS = max(SX,SY) = SY
- JMP SHORT L68
- L66a:
- MOV AXIS,CX ; No, AXIS = min(SX,SY) = SY
- MOV BIAS,DX ; and BIAS = max(SX,SY) = SX
-
- L68:
- MOV DX,AXIS
- SUB DX,BIAS
- MOV DIAG,DX ; DIAG := AXIS - BIAS
- L69:
- MOV DX,BIAS
- NEG DX ; -BIAS
- DEC DX ; -BIAS-1
- CMP word ptr DIAGX,0000H ; DIAGX < 0?
- JGE I14 ; No
- L70:
- DEC DX ; Yes, form -BIAS-2
- I14:
- L71:
- MOV NDIST,DX ; NDIST is always negative
- L72:
- NEG DX ; -NDIST is positive
- SAR DX,1 ; ((-NDIST) DIV 2)
- NEG DX ; (NDIST DIV 2)
- ADD DX,AXIS ; (NDIST DIV 2) + AXIS
- MOV NDIST,DX ; NDIST := AXIS + NDIST DIV 2
- L73:
- MOV DX,SX
- CMP DX,SY ; SX >= SY?
- JGE L73a ; Yes
- MOV DX,SY ; MAX(SX,SY)
- L73a:
- INC DX ; MAX(SX,SY) + 1
- MOV NUMPNT,DX ; NUMPNT := MAX(SX,SY) + 1
-
- ; Allocate IX, IY, I, NDIST to registers CX, DX, SI, and DI, and set
- ; video function codes in AH,AL outside of loop
-
- L74:
- MOV CX,IX0 ; IX := IX0
- L75:
- MOV DX,IY0 ; IY := IY0
- L76:
- MOV SI,0001H ; I := 1
- MOV DI,NDIST
- MOV AL,81H ; want exclusive-OR with current color
- MOV AH,$VIDEO_SETDOT ; code to set a dot in video map
-
- I18: ; Start of loop over I
- CMP SI,NUMPNT ; I < NUMPNT?
- JGE I17 ; No, exit loop
- L78:
- INT $VIDEO ; set the dot
- L79:
- TEST DI,DI ; NDIST < 0?
- JGE I19 ; No
- L81:
- ADD DI,AXIS ; Yes, NDIST := NDIST + AXIS
- L82:
- ADD CX,AXISX ; IX := IX +AXISX
- L83:
- ADD DX,AXISY ; IY := IY + AXISY
- INC SI ; I := I + 1 for next iteration
- JMP short I18 ; Loop back to test limits
- I19:
- L87: ; here when NDIST >= 0
- ADD DI,DIAG ; NDIST := NDIST + DIAG
- L88:
- ADD CX,DIAGX ; IX := IX + DIAGX
- L89:
- ADD DX,DIAGY ; IY := IY + DIAGY
- INC SI ; I := I + 1 for next iteration
- JMP short I18 ; Loop back to test limits
- I17:
- L92: ; here at loop end to set final dot
- INT $VIDEO ; set the dot ((CX,DX) = (IX,IY) = (col,row))
-
- I7: ; here when done
- ADD SP,SPBIAS ; Restore original SP at entry
- POP BP ; and caller's frame pointer
- RET 2*ARGCNT ; and return discarding stack arguments
- DDIIL ENDP
- $DDIIL ENDS
- END